/**
 * Copyright (c) 2013 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. 
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners. 
 * See LICENSE.TXT for license information.
 */

package com.nokia.example.composedui.utils;

import java.util.NoSuchElementException;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;

import com.nokia.example.composedui.ViewManager;
import com.nokia.example.composedui.model.DataItem;
import com.nokia.example.composedui.model.ItemStorage;

/**
 * A generic dialog which state can be saved and restored.
 */
public class Confirmation
    extends Alert
    implements CommandListener, PersistableState
{
    // Constants
    public static final Command OK_COMMAND = new Command("", Command.OK, 1);
    public static final Command CANCEL_COMMAND = new Command("", Command.CANCEL, 1);
    private static final String STORAGE_ID_FOR_CONFIRM_BODY_TEXT = "confirmationBodyText";
    private static final String STORAGE_ID_FOR_CONFIRM_CONFIRM_TEXT = "confirmationConfirmText";
    private static final String STORAGE_ID_FOR_CONFIRM_CANCEL_TEXT = "confirmationCancelText";

    // Members
    private CommandListener forwardedCommandListener;
    private Command realOkCommand;
    private Command realCancelCommand;

    /**
     * Constructor.
     */
    public Confirmation() {
        super("Confirm");
        this.setCommandListener(this);
    }

    /**
     * Constructor.
     * @param text The message to display in the alert.
     * @param confirmButtonText The text for the OK command.
     * @param cancelButtonText The text for the CANCEL command.
     * @param commandListener The command listener to be notified.
     */
    public Confirmation(String text,
                        String confirmButtonText,
                        String cancelButtonText,
                        CommandListener commandListener)
    {
        super("Confirm");
        addContent(text, confirmButtonText, cancelButtonText);
        setCommandListener(this);
        restoreCommandListener(commandListener);
    }

    /**
     * @see PersistableState#restoreInstance(DataItem, ItemStorage, ViewManager, AppDataStorage, String)
     */
    public void restoreInstance(DataItem selectedDataItem,
                                ItemStorage itemStorage,
                                ViewManager viewManager,
                                AppDataStorage appDataStorage,
                                String uniqueId)
    {
        String text = appDataStorage.valueByKey(uniqueId + STORAGE_ID_FOR_CONFIRM_BODY_TEXT);
        String confirmButtonText = appDataStorage.valueByKey(uniqueId + STORAGE_ID_FOR_CONFIRM_CONFIRM_TEXT);
        String cancelButtonText = appDataStorage.valueByKey(uniqueId + STORAGE_ID_FOR_CONFIRM_CANCEL_TEXT);
        
        if (text != null && confirmButtonText != null && cancelButtonText != null) {
            addContent(text, confirmButtonText, cancelButtonText);
        }
        else {
           throw new NoSuchElementException("No data available to reconstruct Confirmation dialog");
        }
    }

    /**
     * @see PersistableState#saveInstance(AppDataStorage, String)
     */
    public void saveInstance(AppDataStorage appDataStorage, String uniqueId) {
        appDataStorage.put(uniqueId + STORAGE_ID_FOR_CONFIRM_BODY_TEXT, getString());
        appDataStorage.put(uniqueId + STORAGE_ID_FOR_CONFIRM_CONFIRM_TEXT, OK_COMMAND.getLabel());
        appDataStorage.put(uniqueId + STORAGE_ID_FOR_CONFIRM_CANCEL_TEXT, CANCEL_COMMAND.getLabel());
    }

    /**
     * Notifies the set command listener.
     * 
     * @see javax.microedition.lcdui.CommandListener#commandAction(Command, Displayable)
     */
    public void commandAction(Command command, Displayable displayable) {
        if (forwardedCommandListener == null) {
            return;
        }
        
        if (command.equals(realOkCommand)) {
            forwardedCommandListener.commandAction(OK_COMMAND, displayable);
        }
        else if (command.equals(realCancelCommand)) {
            forwardedCommandListener.commandAction(CANCEL_COMMAND, displayable);
        }
    }

    /**
     * Sets the command listener to be notified if any command in this alert
     * are invoked.
     * @param commandListener The command listener to notify.
     */
    public void restoreCommandListener(CommandListener commandListener) {
        forwardedCommandListener = commandListener;
    }

    /**
     * Sets the content of this alert.
     * @param text The message to display in the alert.
     * @param confirmButtonText The text for the OK command.
     * @param cancelButtonText The text for the CANCEL command.
     */
    private void addContent(String text,
                            String confirmButtonText,
                            String cancelButtonText) {
        setString(text);
        realOkCommand = new Command(confirmButtonText, Command.OK, 1);
        realCancelCommand = new Command(cancelButtonText, Command.CANCEL, 1);
        addCommand(realOkCommand);
        addCommand(realCancelCommand);
    }
};